<?php

namespace app\admin\controller;
use think\Db;
use think\Request;
use org\Jdk_inc;


class Refund extends Common
{
    // 订单管理
    public function index()
    {
        if (request()->isPost()) {
            $data = input('post.');
            $page = input('page') ? input('page') : 1;
            $pageSize = input('limit') ? input('limit') : config('common.page_sizes');
            $phone = input('post.phone');
            $status = input('post.status');
            $paytime = input('post.paytime');
            $oldtime = input('post.oldtime');
            $order_number = input('post.order_number');
            $where = array();
            $where['o.status']=['in',[2,3,4]];
            if(isset($phone)){
                $where['u.phone']=$phone;
            }
            if(isset($status)){
                $where['o.status'] = $status;   
            }
            if(isset($order_number)){
                $where['o.order_number'] = $order_number;
            }
            if(isset($paytime) && isset($oldtime)){
                $where['o.paytime'] = array('between',$paytime.','.$oldtime);
            }else{
                if(isset($oldtime)){
                    $where['o.paytime']=array('elt',$oldtime);
                }
                if(isset($paytime)){
                    $where['o.paytime']=array('egt',$paytime);
                }
            }
            $list = db('order')
                ->alias('o')
                ->join('user u', 'o.user_id = u.user_id')
                ->join('room r', 'o.room_id =r.id')
                ->join('room_cate c', 'r.two_cate = c.id')
                ->where($where)
                ->order('o.order_id desc')
                ->field('o.order_id as id,r.one_cate as one_cate,o.refund_type as refund_type,c.title as two_cate,o.order_number as order_number,u.realname as realname,u.phone as phone,o.days as days,o.money as money,o.addtime as addtime,o.status as status,o.type as type')
                ->paginate(array('list_rows' => $pageSize, 'page' => $page))
                ->toArray();
            $list = model('Order')->listAddTimeInfo($list);
            return $result = ['code' => 0, 'msg' => config('common.data_success'), 'data' => $list['data'], 'count' => $list['total'], 'rel' => 1];
        }
        return $this->fetch('');
    }
    
    //审核通过
    public function pass(){
        
        
        $order_id = input('order_id');
        $check_reason = input('check_reason');
        
        //查看订单支付类型
        $order = db('order')->where(['status'=>2,'order_id'=>$order_id])->find();
        
        if(empty($order)) return json(['code'=>0,'msg'=>"订单信息错误"]);
        
        if($order['type']==0){
            
                $result = $this->wxrefundapi($order_id);
         
                if (($result['return_code'] == 'SUCCESS') && ($result['result_code'] == 'SUCCESS')) {
        
                    //退款成功的操作 订单号  更改订单状态
                    $trade_no = $result['out_trade_no'];
                    
                    $order = db("order")->where('order_number', $trade_no)->find();
                    
                    db("order")->where('order_number', $trade_no)->update(['status' => 3,'check_reason'=>$check_reason]);
                    
                    //记录表加数据
                    $data = [
                        'user_id' => $order['user_id'],
                        'money'=> $order['money'],
                        'addtime'=>time(),
                        'ordertype' => 7,
                        'status' => 1,
                        'order_id' => $trade_no,
                        'desc' => "微信预订房间退款", 
                        ];
                    db('user_consumption')->insert($data);
                    
                    $room = db('room')->where(['id'=>$order['room_id']])->find();
                    
                    //增加房间次数
                    db('room')->where(['id'=>$order['room_id']])->setInc('room_num',$order['room_num']);
                    
                    
                    db('room')->where(['id'=>$order['room_id']])->setDec('order_num',$order['room_num']);
                    
                    db('user')->where(['user_id'=>$order['user_id']])->setDec('consumption_money',$order['money']);
                    db('user')->where(['user_id'=>$order['user_id']])->setDec('real_money',$order['money']);
                    
                    //更改vip等级
                    // $user = db('user')->where(['user_id'=>$order['user_id']])->find();
                    // $vip = db('vip_upgrade')->where(['user_id'=>$user['user_id'],'new_level'=>$user['level']])->find();
                    checkLevel($order['user_id']);
                    //发送模板消息
                    $this->send($order_id,1,0);
                    
                    return json(['code'=>1,'msg'=>"退款成功"]);
                    
                    
        
                } else if (($result['return_code'] == 'FAIL') || ($result['result_code'] == 'FAIL')) {
                    
                    //退款失败原因
                    $reason = (empty($result['err_code_des']) ? $result['return_msg'] : $result['err_code_des']);
                    
                    return json(['code'=>0,'msg'=>$reason]);
                    
                    
        
                } else {
        
                   
                    return json(['code'=>0,'msg'=>"退款失败"]);
                }
                
        }elseif($order['type']==1){//次卡支付
            
            $result = $this->secondback($order_id);
            
            return json($result);
            
        }elseif($order['type']==2){//余额支付
            
            $result = $this->rechargeback($order_id);
            
            return json($result);
            
        }
        
       
        
        
    }
    
    
    //次卡支付退款
    public function secondback($order_id){
        
        $order = db('order')
            ->where(['order_id' => $order_id, 'status' => 2,'type'=>1]) 
            ->find();
            
        if (empty($order)) {
            
            return $result = ['code' => 0, 'msg' => "订单状态错误"];
        }
        
       
        //直接退款
        db('order')->where(['order_id'=>$order_id])->update(['status'=>3]);
        
        //用户次卡次数增加
        $need_num = $order['days']*$order['room_num'];
        
        db('user')->where(['user_id'=>$order['user_id']])->setInc('second_num',$need_num);
        
        $room = db('room')->where(['id'=>$order['room_id']])->find();
        
        //增加房间次数
        db('room')->where(['id'=>$order['room_id']])->setInc('room_num',$order['room_num']);
    
        
        
        db('room')->where(['id'=>$order['room_id']])->setDec('order_num',$order['room_num']);
        
        //增加次卡的库存
        // db('second_card')->where(['id'=>$order['card_id']])->setInc('number',1);
        //余额记录表加记录
        $data = [
                'user_id' => $order['user_id'],
                'money' => $order['money'],
                'addtime' => time(),
                'ordertype' => 11,
                'status' => 1,
                'order_id' => $order['order_number'],
                'desc' => "次卡预订房间退款",
                'second_num' => $need_num,
            ];
            
        db('user_consumption')->insert($data);
         
        //发送模板消息
        $this->send($order_id,1,1);
        
        return $result = ['code' => 1, 'msg' => "退款成功"];
        
    }
    
    
    //余额支付退款
    public function rechargeback($order_id){
        
        
        $order = db('order')
            ->where(['order_id' => $order_id, 'status' => 2,'type'=>2]) 
            ->find();
        if (empty($order)) {
            return $result = ['code' => 0, 'msg' => "订单状态错误"];
        }
        
        
        //直接退款
        db('order')->where(['order_id'=>$order_id])->update(['status'=>3]);
        
        //增加用户的余额
        db('user')->where(['user_id'=>$order['user_id']])->setInc('money',$order['money']);
        
        
        $room = db('room')->where(['id'=>$order['room_id']])->find();
         
        //增加房间次数
        db('room')->where(['id'=>$order['room_id']])->setInc('room_num',$order['room_num']);
    
         
        db('room')->where(['id'=>$order['room_id']])->setDec('order_num',$order['room_num']);
        
        // //增加储值卡次数
        // db('recharge_card')->where(['id'=>$order['card_id']])->setInc('number',1);
        
        //余额记录表加记录
        $data = [
                'user_id' => $order['user_id'],
                'money' => $order['money'],
                'addtime' => time(),
                'ordertype' => 12,
                'status' => 1,
                'order_id' => $order['order_number'],
                'desc' => "余额预订房间退款",
            ];
            
        db('user_consumption')->insert($data);
        
        
        //发送模板消息
        $this->send($order_id,1,2);
        
        return $result = ['code' => 1, 'msg' => "退款成功"];
        
        
    }
    
     
    
    //审核驳回
    public function reject(){
        
        
        $order_id = input('order_id');
        $check_reason = input('check_reason');
        
        $order = db("order")->where('order_id', $order_id)->find();
         
        $this->send($order_id,2,$order['type']); 
        
        db("order")->where('order_id', $order_id)->update(['status' => 4,'check_reason'=>$check_reason]);
        
        return json(['code'=>1,'msg'=>"驳回成功"]);
        
    }
    
    
    
    private function wxrefundapi($id)
    {   
        $wxpay = db("weixin_config")->find(1);
        
        //查询订单,根据订单里边的数据进行退款
        $order = db('order')
            ->where(['order_id' => $id, 'status' => 2,'type'=>0])
            ->field('order_id,order_number,money,status')
            ->find();
        if (empty($order)) {
            return $result = ['code' => 0, 'msg' => "订单状态错误"];
        }
        

        $setout_refund_no = strtotime(date('YmdHis', time())) . substr(microtime(), 2, 6) . sprintf('%03d', rand(100, 999));
        

        //通过微信api进行退款流程
        $parma = array(
            'appid' => $wxpay['wx_appid'], //公众账号ID
            'mch_id' => $wxpay['mch_id'], //商户号
            'nonce_str' => $this->createNoncestr(32), //随机字符串
            'out_refund_no' => $setout_refund_no, //商户退款单号
            'out_trade_no' => $order['order_number'], //商户订单号
            'total_fee' => $order['money'] * 100, //订单金额
            'refund_fee' => $order['money'] * 100, //退款金额
        );

        $stringA = $this->artxun_param_sort($parma) . '&key=' . $wxpay['wx_key'];
        $parma['sign'] = strtoupper(md5($stringA));

        $xmldata = $this->arrayToXml($parma);

        $xmlresult = $this->postXmlSSLCurl($xmldata, 'https://api.mch.weixin.qq.com/secapi/pay/refund');
        $result = $this->xmlToArray($xmlresult);

        return $result;
    }
    
    
     //发送模板消
    public function send($order_id,$type,$status)
    {   
		//查询订单
		$order = db('order')->where(['order_id' => $order_id])->find();
	    
		//查询用户
		$openid = db('user')->where(['user_id'=>$order['user_id']])->value('openid');
		
		if($type==1){//退款成功
		
		    $remark = db('smg_reply')->where(['id'=>3])->value('content');      
		    
		}elseif($type==2){//退款驳回
		    $remark = db('smg_reply')->where(['id'=>4])->value('content');      
		    
		} 
	    
	    if($status==0){
	        $keyword3 = "微信";
	    }elseif($status==1){
	        $keyword3 = "次卡";
	    }elseif($status==2){
	        $keyword3 = "余额";
	    }
	    
		$url = request()->server("REQUEST_SCHEME") . "://" . $_SERVER['SERVER_NAME']."/mobile/orderman.html";
        $template = array(
            'touser' => $openid,
            'template_id' => "E9oX-zmbu1lkz3CjnItrPyKWC26ZYWtbnk_aJqV3WOA", //这个是模版ID，获取方法自己看文档很详细。
            'url' => $url,
            'topcolor' => "#7B68EE",
            'data' => array(
                'first' => array('value' => "订单退款审核通知", 'color' => "#F70997"),
                'keyword1' => array('value' => $order['order_number'], 'color' => '#000'),
                'keyword2' => array('value' => $order['money'], 'color' => '#000'),
                'keyword3' => array('value' => $keyword3, 'color' => '#000'),
                'keyword4' => array('value' => date('Y-m-d H:i:s'), 'color' => '#000'),
                'remark'  => array('value' => $remark, 'color' => '#000'),
            )
        );
        $this->sendMessage($template);
    }
    
    
    //发送模板消息
    public function sendMessage($template)
    {   
        $jdk = new Jdk_inc();
        
        //获取access_token
        $access_token = $jdk->getToken(); 
         
        $json_template = json_encode($template);
        $url = 'https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=' . $access_token;
        $res = $this->httpPost($url, $json_template);      //以post方式 向用户发送数据
        return $res;
    }
    
    //模板消息
    public function httpPost($url,$data) {
    	$curl = curl_init();
    	curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    	curl_setopt($curl, CURLOPT_TIMEOUT, 500);
    	curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    	curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
    	curl_setopt($curl, CURLOPT_URL, $url);
    	curl_setopt($curl, CURLOPT_POST, true);
    	curl_setopt($curl, CURLOPT_POSTFIELDS,$data);
    	$res = curl_exec($curl);
    	curl_close($curl);
    	return $res;
    }
    
    
    

    //参数排序
    public function artxun_param_sort(array &$parma)
    {
        if (!ksort($parma)) {
            throw new Exception('参数排序失败');
        }
        $arr_temp = array();
        foreach ($parma as $k => $v) {
            if (is_array($v)) {
                $sarr_temp = array();
                foreach ($v as $kk => $vv) {
                    if (!ksort($vv)) {
                        throw new Exception('参数排序失败');
                    }

                    foreach ($vv as $dk => $dv) {
                        $sarr_temp[] = "{$dk}={$dv}";
                    }
                }
                $arr_temp[] = sprintf('%s=%s', $k, implode('&', $sarr_temp));
            } else {
                $arr_temp[] = "{$k}={$v}";
            }

        }
        // 将数组拼接成字符串，以key=value&key=value的形式进行拼接，注意这里不能直接调用
        // http_build_query方法，因为该方法会对参数进行URL编码
        return implode('&', $arr_temp);
    }


    //作用：产生随机字符串，不长于32位
    private function createNoncestr($length = 32)
    {
        $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i++) {
            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        return $str;
    }



    //数组转XML
    private function arrayToXml($arr)
    {
        $xml = "<xml>";
        foreach ($arr as $key => $val) {
            if (is_numeric($val)) {
                $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
            } else {
                $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
            }
        }
        $xml .= "</xml>";
        return $xml;
    }

    //xml转换成数组
    private function xmlToArray($xml)
    {

        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);

        $xmlstring = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);

        $val = json_decode(json_encode($xmlstring), true);

        return $val;
    }



    //需要使用证书的请求
    private function postXmlSSLCurl($xml, $url, $second = 30)
    {
        $ch = curl_init();
        //超时时间
        curl_setopt($ch, CURLOPT_TIMEOUT, $second);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        //设置header
        curl_setopt($ch, CURLOPT_HEADER, false);
        //要求结果为字符串且输出到屏幕上
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        //设置证书
        //使用证书：cert 与 key 分别属于两个.pem文件
        //默认格式为PEM，可以注释
        curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');
        curl_setopt($ch, CURLOPT_SSLCERT,ROOT_PATH. '/extend/cert/apiclient_cert.pem');
        //默认格式为PEM，可以注释
        curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');
        curl_setopt($ch, CURLOPT_SSLKEY, ROOT_PATH . '/extend/cert/apiclient_key.pem');
        //post提交方式
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
        $data = curl_exec($ch);
        //返回结果
        if ($data) {
            curl_close($ch);
            return $data;
        } else {
            $error = curl_errno($ch);
            echo "curl出错，错误码:$error" . "<br>";
            curl_close($ch);
            return false;
        }
    }
    
    
    // 订单查询
    public function edit()
    {
        if (request()->isPost()) {
            $data = input('post.');
            return model('order')->orderData($data, '修改成功!', '修改失败，请重试!');
        } else {
            $id = input('id');
            $list = db('order')
                ->alias('o')
                ->join('user u','o.user_id = u.user_id')
                ->join('room r','r.id = o.room_id')
                ->join('room_cate c','r.two_cate = c.id ')
                ->join('invoice i','o.invoice_id = i.id','LEFT')
                ->where(['o.order_id' => $id])
                ->field(
                    'o.order_id as order_id,o.order_number as order_number,r.one_cate as one_cate,c.title as two_cate,
                    r.is_activity as is_activity,o.days as days,o.addtime as addtime,o.paytime as paytime,o.type as type,
                    o.money as money,o.in_time as in_time,o.out_time as out_time,o.invoice_id as invoice_id,
                    i.cate_id as invoice_cateid,i.name as name,i.company as company,i.indentify_num as indentify_num,check_reason,refund_type,refund_note,invoice_status,
                    i.address as address,i.phone as phone,i.bank as bank,i.number as number,o.idcard as idcard,o.status as status,o.userlist as userlist,o.refund_type as refund_type,o.refund_note as refund_note')
                ->order('o.order_id desc')
                ->find();
                $userlist = unserialize($list['userlist']);
                foreach ($userlist as $i => $item) {
                    if(!isset($item['name'])){
                        $userlist[$i]['name'] = '';
                    }
                    if(!isset($item['phone'])){
                        $userlist[$i]['phone'] = '';
                    }
                    if(!isset($item['sex'])){
                        $userlist[$i]['sex'] = '3';
                    }
                    if(!isset($item['idcard'])){
                        $userlist[$i]['idcard'] = '';
                    }
                    if(!isset($item['address'])){
                        $userlist[$i]['address'] = '';
                    }
                }
            $list['userlist'] = $userlist;
            // var_dump(Db::table('order')->getLastSql());die();
            return $this->fetch('', ['list' => $list]);
        }
    }

}
